<script lang="ts" context="module">
  import {
    CellType,
    CellEditComponentType,
    isCheckCellEditComponentTypeFunc,
    type Column,
    type Row,
  } from "./conf";
  import TextCell from "./TextCell.svelte";
  import ButtonCell from "./ButtonCell.svelte";
  import InputCell from "./InputCell.svelte";
  import LinkCell from "./LinkCell.svelte";
  import DropdownCell from "./DropdownCell.svelte";
  import CheckBoxCell from "./CheckBoxCell.svelte";
</script>

<script lang="ts">
  import el from "date-fns/locale/el";
  import IconCell from "./IconCell.svelte";

  import { createEventDispatcher } from "svelte";
  type T = $$Generic;

  export let checkable: boolean;
  export let editable: boolean;
  export let draggable: boolean;
  export let inlineOp: boolean;
  export let editingRowIndex = -1;
  export let cols: Column[] = [];
  export let rowIndex: number = -1;
  export let rowData: T;
  export let checked: boolean;
  export let makeDraggable;

  const dispatch = createEventDispatcher();
  const row: Row<T> = {
    index: rowIndex,
    checked: false,
    rowData,
  };

  $: rowEditing = editingRowIndex === rowIndex;
  $: rowEditable = editable && !rowEditing;

  $: cellEdiable = (col: Column) => {
    return editable && col?.options?.editable;
  };
  function getCellComponentType(col: Column): CellEditComponentType {
    if (isCheckCellEditComponentTypeFunc(col.options.editType)) {
      return col.options.editType(rowData);
    }
    return col.options.editType;
  }
  function handleClick() {
    if (!checkable) {
      row.checked = checked = true;
      dispatch("select-row", row);
    } else {
      row.checked = checked = !checked;
      dispatch("change-row-checked", row);
    }
  }
  function handleDblClick() {
    if (rowEditable) {
      editingRowIndex = rowIndex;
      dispatch("change-row-editingindex", rowIndex);
    }
  }
  function handleSave() {
    if (rowEditing) {
      dispatch("save-row-editing", rowIndex);
    }
  }
  function handleCancelEdit() {
    if (rowEditing) {
      dispatch("cancel-row-editing", rowIndex);
    }
  }
  function handleCheckChange(e) {
    // e.target.checked = checked = !checked;
    // e.target.indeterminate = false;
    // dispatch("change-row-checked", {
    //   checked: checked
    // })
  }
  export const selectAll = () => {};
  function handleCreateNew() {
    dispatch("create-new-row", rowIndex);
  }
  function handleRemove() {
    dispatch("remove-row", rowIndex);
  }
  function handleUpdateCell(e) {
    console.warn("---handleUpdateCell---");
    dispatch("change-cell-content", {
      rowIndex,
      ...e.detail,
    });
  }
</script>

<tr
  class="border-b border-opacity-20 dt-row"
  class:dt-row-active={checked}
  on:click={handleClick}
  on:dblclick={handleDblClick}
>
  {#if draggable}
    <td
      class="dt-cell flex flex-nowrap items-center select-none cursor-ns-resize"
      use:makeDraggable
    >
      <ButtonCell icon={"menu"} title="拖动行" />
    </td>
  {/if}
  {#if checkable}
    <td class="dt-cell w-8 px-2 pt-2">
      <input
        type="checkbox"
        class="rounded-sm"
        name="Box_{rowIndex}"
        bind:checked
        on:change={handleCheckChange}
      />
    </td>
  {/if}
  {#each cols as col}
    <td class="dt-cell">
      {#if cellEdiable(col) && rowEditing}
        {#if getCellComponentType(col) === CellEditComponentType.Dropdown}
          <DropdownCell
            {col}
            value={rowData[col.key]}
            entries={col.options.dropdownOption?.dropdownEntries}
            on:update-cell={handleUpdateCell}
          />
        {:else if getCellComponentType(col) === CellEditComponentType.CheckBox}
          <CheckBoxCell
            {col}
            checked={rowData[col.key]}
            on:update-cell={handleUpdateCell}
          />
        {:else if getCellComponentType(col) === CellEditComponentType.Input}
          <InputCell
            {col}
            value={rowData[col.key]}
            on:update-cell={handleUpdateCell}
          />
        {:else}
          <TextCell {col} value={rowData[col.key]} />
        {/if}
      {:else}
        {#if col.options?.type}
          {#if CellType.Button === col.options.type && !rowEditing}
            <ButtonCell
              item={rowData}
              icon={col.options.icon}
              title={col.options.text}
              action={col.options.buttonOption?.action}
            />
          {:else if CellType.Link === col.options.type && !rowEditing}
            <LinkCell {col} item={rowData} to={col.options.linkOption?.href} />
          {:else if CellType.Icon === col.options.type}
            <IconCell {col} item={rowData} icon={col.options.icon} />
          {:else}
            <TextCell {col} value={rowData[col.key]} />
          {/if}
        {:else}
          <TextCell {col} value={rowData[col.key]} />
        {/if}
      {/if}
    </td>
  {/each}
  {#if inlineOp}
    <td class="dt-cell flex flex-nowrap items-center justify-center">
      <!-- <ButtonCell icon={"plus"} action={handleCreateNew} /> -->
      {#if rowEditable}
        <ButtonCell
          icon={"pencil-alt"}
          action={handleDblClick}
          title="编辑行"
        />
        <ButtonCell icon={"trash"} action={handleRemove} title="删除行" />
      {:else if rowEditing}
        <ButtonCell action={handleSave} title="保存行" text="保存" />
        <ButtonCell action={handleCancelEdit} title="取消编辑行" text="取消" />
      {/if}
    </td>
  {/if}
</tr>

<style lang="postcss">
  .dt-row {
    background-color: #0d1117;
    border-color: #30363d;
  }
  .dt-cell {
    height: calc(var(--dt-row-height) * 1px);
  }
  .dt-row:hover {
    background-color: #161b22;
    border-color: #21262d;
  }
  .dt-row-active {
    background-color: #161b22;
    border-color: #21262d;
  }
  /* .dt-row-active:hover {

  } */
</style>
